﻿using ttbit.WorkingSpace;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ttbit.core;
using static System.ComponentModel.Design.ObjectSelectorEditor;
using pixeleditor.Editor;
using pixeleditor.Log;
using System.Drawing;
using OpenTK.WinForms;
using OpenTK.Graphics.ES30;
using pixeleditor.WorkingSpace.Resource;

namespace spriteeditor
{
    public class EditorApp
    {
        Form1 form;
        public EditorApp()
        {
            if (Instance != null)
                throw new Exception("EditorApp只能有一个");
            Instance = this;

        }
        public static EditorApp Instance
        {
            get;
            private set;
        }
        public Renderer.TTRender2 graphics
        {
            get;
            private set;
        }
        public WorkingSpace workingSpace
        {
            get;
            private set;
        }
        public ResourceMgr resmgr
        {
            get;
            private set;
        }
        GLControl glc;
        void RegResource()
        {
            //RegEditor
            RegResource(Resource_Texture.TypeStr, new Editor_Texture(), new Parser_Texture());
            RegResource(Resource_Sprite.TypeStr, new Editor_Sprite(), new Parser_Sprite());
            RegResource(Resource_Text.TypeStr, new Editor_Text(), new Parser_Text());
            RegResource(Resource_Atlas.TypeStr, new Editor_Atlas(), new Parser_Atlas());

        }
        public void Init(Form1 form)
        {
            this.form = form;
            resmgr = new ResourceMgr(this);

            RegResource();

            workingSpace = new WorkingSpace(this);
            workingSpace.InitHistory();



            graphics = new Renderer.TTRender2();
            var root = form.splitContainer5.Panel1;
            root.Controls.Clear();

            glc = graphics.Init(root);

            bool down = false;
            glc.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    down = true;
                    this.OnPointDown(form.propertyGrid1.SelectedObject as INodeTag, e.X, e.Y);
                }
            };
            glc.MouseUp += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    down = false;
                    this.OnPointUp(form.propertyGrid1.SelectedObject as INodeTag, e.X, e.Y);
                }
            };
            glc.MouseMove += (s, e) =>
            {
                if (down)
                {
                    this.OnPointMove(form.propertyGrid1.SelectedObject as INodeTag, e.X, e.Y);
                }
            };
            glc.MouseLeave += (s, e) =>
            {
                down = false;
            };

        }
        public void OnRender()
        {


            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

            graphics.BeginRender(glc.Width, glc.Height);
            GetEditor()?.OnRender(graphics);
            graphics.EndRender();
            glc.SwapBuffers();

            if (SelectResource != null)
            {
                if (labelDirty != null)
                {
                    if (SelectResource.Dirty)
                    {
                        labelDirty.Text = "资源改变，注意保存";
                        btnSave.Enabled = true;
                        btnRevert.Enabled = true;
                    }
                    else
                    {
                        labelDirty.Text = "资源最新";
                        btnSave.Enabled = false;
                        btnRevert.Enabled = false;
                    }
                }
            }
        }
        public ILogger logger
        {
            get
            {
                return form;
            }
        }

        public INodeTag SelectNode
        {
            get;
            private set;
        }
        public IWorkResource SelectResource
        {
            get;
            private set;
        }
        public IWorkResourceEditor GetEditor()
        {
            if (SelectResource != null)
            {
                if (editors.TryGetValue(SelectResource.TypeName, out var editor))
                {
                    return editor;
                }
            }
            return null;
        }
        void RegResource(string typename, IWorkResourceEditor editor, IWorkResourceParser parser)
        {
            if (typename != editor.TypeName)
            {
                throw new Exception("error Editor,need:" + typename + " but:" + editor.TypeName);
            }
            if (typename != parser.TypeName)
            {
                throw new Exception("error Parser,need:" + typename + " but:" + parser.TypeName);
            }
            editors.Add(editor.TypeName, editor);
            resmgr.RegParser(parser);
        }
        Dictionary<string, IWorkResourceEditor> editors = new Dictionary<string, IWorkResourceEditor>();

        public void OnSelect(TreeNode node, INodeTag tag)
        {
            form.flowStruct.Controls.Clear();
            form.flowFunction.Controls.Clear();
            form.flowInspector.Controls.Clear();

            SelectResource = null;
            form.propertyGrid1.SelectedObject = SelectNode = tag;


            if (tag != null)
            {

                if (tag is NodeTag_Meta meta)
                {
                    OnSelectMeta(meta);
                }
                else if (tag is Nodetag_Folder folder)
                {
                    OnSelectFolder(folder.Folder);
                }
            }
        }
        public FlowLayoutPanel EditorAreaStruct
        {
            get
            {
                return form.flowStruct;
            }
        }
        public FlowLayoutPanel EditorAreaFunction
        {
            get
            {
                return form.flowFunction;
            }
        }
        public FlowLayoutPanel EditorAreaInspector
        {
            get
            {
                return form.flowInspector;
            }
        }
        Label labelDirty = null;
        Button btnSave = null;
        Button btnRevert = null;
        private void OnSelectMeta(NodeTag_Meta meta)
        {
            var root = form.flowInspector;
            EditorAreaFunction.Controls.Clear();
            EditorAreaStruct.Controls.Clear();
            root.Controls.Clear();

            var name = meta.meta.Name;

            GetEditor()?.OnDeactive(this);

            form.propertyGrid1.SelectedObject = SelectResource = resmgr.GetResource(name).Value;

            var parsers = resmgr.GetParsersByExt(meta.meta.Ext);
            if (parsers.Length > 0)
            {
                //更改meta类型逻辑


                //选类型行
                {

                    var line = new FlowLayoutPanel();

                    line.FlowDirection = FlowDirection.LeftToRight;
                    line.AutoSize = true;
                    var cbox = new ComboBox();
                    foreach (var par in parsers)
                    {
                        cbox.Items.Add(par.TypeName);
                    }
                    cbox.Text = meta.meta.Type;
                    line.Controls.Add(cbox);
                    var btn = new Button();
                    btn.Text = "Change";
                    btn.Enabled = false;
                    line.Controls.Add(btn);
                    cbox.SelectedIndexChanged += (s, e) =>
                    {
                        if (SelectResource.TypeName != cbox.Text)
                        {
                            btn.Enabled = true;
                        }
                        else
                        {
                            btn.Enabled = false;
                        }
                    };
                    btn.Click += (s, e) =>
                    {
                        resmgr.GetResource(meta.meta.Name).ForceDispose();
                        resmgr.ClearUnuseResource();

                        FileInfo fileInfo = new FileInfo(meta.meta.srcfile);
                        workingSpace.ReImport(cbox.Text, fileInfo);

                        meta.meta.Init(cbox.Text, fileInfo);


                        OnSelectMeta(meta);
                    };
                    root.Controls.Add(line);

                }
                //资源更新行
                {

                    var line = new FlowLayoutPanel();

                    line.FlowDirection = FlowDirection.LeftToRight;
                    line.AutoSize = true;

                    labelDirty = new Label() { Text = "Dirty", Width = 120, Height = 24 };
                    line.Controls.Add(labelDirty);

                    btnSave = new Button() { Text = "Save", AutoSize = true };
                    btnSave.Enabled = false;
                    line.Controls.Add(btnSave);
                    btnSave.Click += (s, e) =>
                    {
                        FileInfo fileInfo = new FileInfo(meta.meta.srcfile);
                        workingSpace.Save(SelectResource, meta.meta.Type, fileInfo);
                    };
                    btnRevert = new Button() { Text = "Revert", AutoSize = true };
                    btnRevert.Enabled = false;
                    line.Controls.Add(btnRevert);
                    btnRevert.Click += (s, e) =>
                    {
                        FileInfo fileInfo = new FileInfo(meta.meta.srcfile);
                        resmgr.GetResource(meta.meta.Name).ForceDispose();
                        resmgr.ClearUnuseResource();
                        OnSelectMeta(meta);
                    };

                    root.Controls.Add(line);
                }

            }

            GetEditor()?.OnActive(this, SelectResource);



            //是一个资源，特殊处理
        }
        void OnSelectFolder(string path)
        {
            var labelPath = new Label() { Text = "CurDir=" + Path.GetRelativePath(this.workingSpace.WorkingPath, path) + "/", AutoSize = true };
            //创建新资源，不是所有资源都可以创建
            var label = new Label() { Text = "在下面输入名字，必须唯一", AutoSize = true };
            var name = new TextBox() { Width = 200, Height = 30 };
            var typecombo = new ComboBox() { Width = 200, Height = 32 };
            foreach (var p in resmgr.GetAllParsers())
            {
                if (p.CanCreate)
                {
                    typecombo.Items.Add(p);
                }
            }
            typecombo.Text = typecombo.Items[0].ToString();

            var btnCreate = new Button() { Text = "创建资源", AutoSize = true };
            var btnCreateFolder = new Button() { Text = "创建目录", AutoSize = true };
            btnCreate.Click += (s, e) =>
            {
                var parser = typecombo.SelectedItem as IWorkResourceParser;
                
                var file = Path.Combine(path, name.Text + parser.FileExt[0]);
                using (var fs = System.IO.File.OpenWrite(file))
                {

                }
                var meta = new MetaInfo();
                meta.Init(parser.TypeName, new FileInfo(file));
                using (var metafs = System.IO.File.OpenWrite(meta.srcfile + ".meta"))
                {
                    meta.Write(metafs);
                }
                workingSpace.RefreshAll();
                form.UpdateFileTree();
                var node = form.FindMetaNode(name.Text.ToLower());
                if (node != null)
                    OnSelect(node, node.Tag as INodeTag);

            };
            btnCreateFolder.Click += (s, e) =>
            {
                try
                {
                    System.IO.Directory.CreateDirectory(Path.Combine(path, name.Text));
                    form.UpdateFileTree();

                    var node = form.FindFolderNode(name.Text.ToLower());
                    if (node != null)
                        OnSelect(node, node.Tag as INodeTag);
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.Message, "err");
                }

            };
            EditorAreaInspector.Controls.Add(labelPath);
            EditorAreaInspector.Controls.Add(label);
            EditorAreaInspector.Controls.Add(name);
            EditorAreaInspector.Controls.Add(typecombo);
            EditorAreaInspector.Controls.Add(btnCreate);
            EditorAreaInspector.Controls.Add(btnCreateFolder);
        }
        public void OnPropChange(INodeTag tag)
        {
            GetEditor()?.OnPropChange();
        }
        int dx = 0;
        int dy = 0;
        int px = 0;
        int py = 0;
        public void OnPointDown(INodeTag tag, int x, int y)
        {
            GetEditor()?.OnPointDown(0, x, y);


        }
        public void OnPointMove(INodeTag tag, int x, int y)
        {
            GetEditor()?.OnPointMove(0, x, y);

        }
        public void OnPointUp(INodeTag tag, int x, int y)
        {
            GetEditor()?.OnPointUp(0, x, y);

        }

    }
}
